Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SDD to PSDD compilation #56

Merged
merged 4 commits into from
Mar 12, 2021
Merged

Conversation

RenatoGeh
Copy link
Contributor

Adds a function convert(::Type{<:StructProbCircuit}, sdd::Sdd) to "convert" an SDD into a PSDD.

There are still some bugs to figure out (tests do not pass), but since this was mentioned in #53, I'm pushing this as a WIP PR.

@guyvdbroeck
Copy link
Member

@talf301 has been working on some basic functionality to resolve this, such as smoothing structured circuits

@talf301
Copy link
Member

talf301 commented Mar 3, 2021

So I've added a version of the function that uses Tractables/LogicCircuits.jl#69 (structured smoothing) to do most of the work. It's passing all of the tests now, so give it a try. The PR isn't actually merged into master yet, so you'll need to make sure you're on the right branch of LogicCircuits first or some weird stuff might happen.

@RenatoGeh
Copy link
Contributor Author

RenatoGeh commented Mar 4, 2021

Wait a second. I was on the right branch for LogicCircuits and activated the right branch, but I forgot to run using LogicCircuits, so I think I'm still using old LogicCircuits.

Thanks, Tal! Unfortunately, I'm getting an error coming from the smooth function here on my end. I suspect you didn't get this error since we sample random vtrees during testing. This might be coming from corner case SDDs with particular vtrees.

Error During Test at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structured_prob_nodes_tests.jl:7
  Got exception outside of a @test
  MethodError: no method matching conjoin(::PlainStruct⋀Node, ::PlainStruct⋁Node, ::PlainStruct⋁Node; reuse=PlainStruct⋀Node(3687726126205023434), use_vtree=nothing)
  Closest candidates are:
    conjoin(::LogicCircuit...) at /home/renatogeh/Juice/LogicCircuits.jl/src/abstract_logic_nodes.jl:113 got unsupported keyword arguments "reuse", "use_vtree"
    conjoin(::PlainStructLogicCircuit, ::PlainStructLogicCircuit; reuse, use_vtree) at /home/renatogeh/Juice/LogicCircuits.jl/src/structured/structured_logic_nodes.jl:129
  Stacktrace:
   [1] #conjoin#238 at /home/renatogeh/Juice/LogicCircuits.jl/src/structured/structured_logic_nodes.jl:126 [inlined]
   [2] smooth_node(::PlainStruct⋀Node, ::BitSet, ::Dict{Int32,LogicCircuit}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:53
   [3] (::LogicCircuits.var"#121#128"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}},BitSet,Dict{Int32,LogicCircuit}})(::PlainStruct⋀Node) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:29
   [4] map!(::LogicCircuits.var"#121#128"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}},BitSet,Dict{Int32,LogicCircuit}}, ::Array{Node,1}, ::Array{PlainStructLogicCircuit,1}) at ./abstractarray.jl:2155
   [5] (::LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}})(::PlainStruct⋁Node, ::LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:27
   [6] f_inner at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:48 [inlined]
   [7] #foldup_rec#18 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:197 [inlined]
   [8] callback at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:196 [inlined]
   [9] #119 at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:18 [inlined]
   [10] map!(::LogicCircuits.var"#119#125"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}},BitSet}, ::Array{Node,1}, ::Array{PlainStruct⋁Node,1}) at ./abstractarray.jl:2155
   [11] (::LogicCircuits.var"#f_a#124")(::PlainStruct⋀Node, ::LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:17
   [12] f_inner at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:48 [inlined]
   [13] #foldup_rec#18 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:197 [inlined]
   [14] callback at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:196 [inlined]
   [15] (::LogicCircuits.var"#120#127"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}})(::PlainStruct⋀Node) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:25
   [16] _mapreduce(::LogicCircuits.var"#120#127"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}}, ::typeof(union), ::IndexLinear, ::Array{PlainStructLogicCircuit,1}) at ./reduce.jl:408
   [17] _mapreduce_dim at ./reducedim.jl:318 [inlined]
   [18] #mapreduce#620 at ./reducedim.jl:310 [inlined]
   [19] mapreduce at ./reducedim.jl:310 [inlined]
   [20] (::LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}})(::PlainStruct⋁Node, ::LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:25
   [21] f_inner at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:48 [inlined]
   [22] #foldup_rec#18 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:197 [inlined]
   [23] callback at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:196 [inlined]
   [24] (::LogicCircuits.var"#119#125"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}},BitSet})(::PlainStruct⋁Node) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:18
   [25] map!(::LogicCircuits.var"#119#125"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}},BitSet}, ::Array{Node,1}, ::Array{PlainStructLogicInnerNode,1}) at ./abstractarray.jl:2155
   [26] (::LogicCircuits.var"#f_a#124")(::PlainStruct⋀Node, ::LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:17
   [27] f_inner at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:48 [inlined]
   [28] #foldup_rec#18 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:197 [inlined]
   [29] callback at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:196 [inlined]
   [30] (::LogicCircuits.var"#120#127"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}})(::PlainStruct⋀Node) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:25
   [31] _mapreduce(::LogicCircuits.var"#120#127"{LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}}, ::typeof(union), ::IndexLinear, ::Array{PlainStructLogicCircuit,1}) at ./reduce.jl:408
   [32] _mapreduce_dim at ./reducedim.jl:318 [inlined]
   [33] #mapreduce#620 at ./reducedim.jl:310 [inlined]
   [34] mapreduce at ./reducedim.jl:310 [inlined]
   [35] (::LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}})(::PlainStruct⋁Node, ::LogicCircuits.Utils.var"#callback#19"{Tuple{Node,BitSet},typeof(nload),typeof(nsave),LogicCircuits.var"#f_leaf#18"{Tuple{Node,BitSet},LogicCircuits.var"#f_con#122",LogicCircuits.var"#f_lit#123"},LogicCircuits.var"#f_inner#19"{Tuple{Node,BitSet},LogicCircuits.var"#f_a#124",LogicCircuits.var"#f_o#126"{Dict{Int32,LogicCircuit}}}}) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:25
   [36] f_inner at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:48 [inlined]
   [37] #foldup_rec#18 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:197 [inlined]
   [38] #foldup#17 at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:179 [inlined]
   [39] #foldup#17 at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:49 [inlined]
   [40] foldup at /home/renatogeh/Juice/LogicCircuits.jl/src/queries.jl:47 [inlined]
   [41] smooth(::PlainStruct⋁Node) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:33
   [42] convert(::Type{StructProbCircuit}, ::Sdd⋁Node) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/structured_prob_nodes.jl:142
   [43] (::var"#apply_test_cnf#16")(::Int64, ::String) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structured_prob_nodes_tests.jl:130
   [44] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structured_prob_nodes_tests.jl:141
   [45] top-level scope at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/Test/src/Test.jl:1115
   [46] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structured_prob_nodes_tests.jl:9
   [47] include(::String) at ./client.jl:457
   [48] normal_run(::String, ::Array{String,1}, ::Int64, ::Bool) at /home/renatogeh/.julia/packages/Jive/GqadW/src/runtests.jl:469
   [49] runtests(::String; skip::Array{String,1}, node1::Array{Any,1}, targets::Array{String,1}, enable_distributed::Bool, stop_on_failure::Bool) at /home/renatogeh/.julia/packages/Jive/GqadW/src/runtests.jl:87
   [50] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/runtests.jl:6
   [51] include(::String) at ./client.jl:457

@RenatoGeh
Copy link
Contributor Author

Disregard my last comment. That was on me. Everything seems to be working. Thanks. :)

Reduced noise during testing and added some more vtrees for testing. Rebased with master to help during merge.

Nomenclature-wise, should we keep this as convert or should this be named compile?

@RenatoGeh RenatoGeh changed the title [WIP] Add SDD to PSDD compilation Add SDD to PSDD compilation Mar 4, 2021
@RenatoGeh RenatoGeh marked this pull request as ready for review March 4, 2021 18:01
@khosravipasha khosravipasha linked an issue Mar 4, 2021 that may be closed by this pull request
@khosravipasha
Copy link
Contributor

This looks good, not sure what is the best convention for the name, convert is probably fine.
I will let @talf301 decide :)

@talf301
Copy link
Member

talf301 commented Mar 9, 2021

Seems like compile is what's used throughout the code currently, so let's go with that.

test/structured_prob_nodes_tests.jl Show resolved Hide resolved
@RenatoGeh
Copy link
Contributor Author

Renamed to compile and rebased with master to make sure everything is working. I did get an error when testing, but I don't think it's related to this PR. Here's the stack trace.

22/23 structurelearner/learner_tests.jl
learn from missing data tests: Error During Test at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structurelearner/learner_tests.jl:58
  Got exception outside of a @test
  AssertionError: Parameters do not sum to one locally: 1.4240442809811358; -0.23455872500071948 -0.4570882012650902
  Stacktrace:
   [1] (::ProbabilisticCircuits.var"#127#128"{BitCircuit{Array{Int32,1},Array{Int32,2}},Array{Float64,1},Float64,Float64})(::StructSumNode) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/parameters.jl:107
   [2] foreach_reset(::ProbabilisticCircuits.var"#127#128"{BitCircuit{Array{Int32,1},Array{Int32,2}},Array{Float64,1},Float64,Float64}, ::StructSumNode) at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:130
   [3] foreach_reset(::ProbabilisticCircuits.var"#127#128"{BitCircuit{Array{Int32,1},Array{Int32,2}},Array{Float64,1},Float64,Float64}, ::StructMulNode) at /home/renatogeh/Juice/LogicCircuits.jl/src/Utils/graphs.jl:127 (repeats 12 times)
   [4] #estimate_parameters_cached!#126 at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/parameters.jl:98 [inlined]
   [5] estimate_parameters_em(::StructSumNode, ::DataFrame; pseudocount::Float64, entropy_reg::Float64, use_sample_weights::Bool, use_gpu::Bool, exp_update_factor::Float64, update_per_batch::Bool) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/parameters.jl:396
   [6] (::ProbabilisticCircuits.var"#pc_split_step#360"{Int64,Float64,Bool,Int64,Bool,Float64,DataFrame,ProbabilisticCircuits.var"#loss#359"{String,String,Nothing,Bool,DataFrame}})(::StructSumNode) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/structurelearner/learner.jl:116
   [7] struct_learn(::StructSumNode; primitives::Array{ProbabilisticCircuits.var"#pc_split_step#360"{Int64,Float64,Bool,Int64,Bool,Float64,DataFrame,ProbabilisticCircuits.var"#loss#359"{String,String,Nothing,Bool,DataFrame}},1}, kwargs::Dict{ProbabilisticCircuits.var"#pc_split_step#360"{Int64,Float64,Bool,Int64,Bool,Float64,DataFrame,ProbabilisticCircuits.var"#loss#359"{String,String,Nothing,Bool,DataFrame}},Tuple{}}, maxiter::Int64, stop::ProbabilisticCircuits.var"#log_per_iter#361"{Int64,Int64,Bool,Bool,Nothing,Nothing,DataFrame,Float64}, verbose::Bool) at /home/renatogeh/Juice/LogicCircuits.jl/src/transformations.jl:446
   [8] learn_circuit(::DataFrame, ::StructSumNode, ::PlainVtreeInnerNode; pick_edge::String, pick_var::String, depth::Int64, pseudocount::Float64, sanity_check::Bool, maxiter::Int64, seed::Nothing, return_vtree::Bool, batch_size::Int64, splitting_data::Nothing, use_gpu::Bool, entropy_reg::Float64, verbose::Bool, max_circuit_nodes::Nothing, max_learning_time::Nothing, has_missing::Bool) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/structurelearner/learner.jl:147
   [9] learn_circuit_miss(::DataFrame; impute_method::Symbol, pick_edge::String, depth::Int64, pseudocount::Float64, entropy_reg::Float64, sanity_check::Bool, maxiter::Int64, seed::Nothing, return_vtree::Bool, verbose::Bool, max_circuit_nodes::Nothing, max_learning_time::Nothing) at /home/renatogeh/Juice/ProbabilisticCircuits.jl/src/structurelearner/learner.jl:57
   [10] #146 at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/Test/src/Test.jl:633 [inlined]
   [11] redirect_stderr(::var"#146#150"{DataFrame}, ::IOStream) at ./stream.jl:1150
   [12] #145 at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/Test/src/Test.jl:632 [inlined]
   [13] open(::var"#145#149"{DataFrame}, ::String, ::Vararg{String,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at ./io.jl:325
   [14] top-level scope at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/Test/src/Test.jl:631
   [15] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structurelearner/learner_tests.jl:64
   [16] top-level scope at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/Test/src/Test.jl:1115
   [17] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/structurelearner/learner_tests.jl:60
   [18] include(::String) at ./client.jl:457
   [19] normal_run(::String, ::Array{String,1}, ::Int64, ::Bool) at /home/renatogeh/.julia/packages/Jive/GqadW/src/runtests.jl:469
   [20] runtests(::String; skip::Array{String,1}, node1::Array{Any,1}, targets::Array{String,1}, enable_distributed::Bool, stop_on_failure::Bool) at /home/renatogeh/.julia/packages/Jive/GqadW/src/runtests.jl:87
   [21] top-level scope at /home/renatogeh/Juice/ProbabilisticCircuits.jl/test/runtests.jl:6
   [22] include(::String) at ./client.jl:457
   [23] top-level scope at none:6

@khosravipasha
Copy link
Contributor

@RenatoGeh Thanks for the change, oh yeah the github actions tests pass. I think have seen this issue, happens for gpu version only, assuming the machine you ran the tests on locally has a gpu. We can merge this one, I will make another issue for this bug.

@khosravipasha khosravipasha merged commit b860c33 into Tractables:master Mar 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compiling an SDD into a PSDD
4 participants